package project

import (
	"encoding/gob"
	"log"
	"math/rand"
	"net"
	"sync"
	"time"
)

// 服务端Accept
func TcpBacklogServer() {

	// 服务端地址
	// adress := ":8080" //Any IP version
	adress := "127.0.0.1:8080"               //IPv4
	listener, err := net.Listen(tcp, adress) //Listen监听
	if err != nil {
		log.Fatalln(err)
	}
	// 关闭监听
	defer listener.Close()
	log.Println("Server is listening on ", tcp, listener.Addr())

	// 接收请求
	for {
		// 阻塞接受
		conn, err := listener.Accept() //Accept接收
		if err != nil {
			log.Println(err)
		}

		// 处理请求,读写
		go func(conn net.Conn) {
			// 日志链接远程地址(client addr)
			log.Println("accept a new link", conn.RemoteAddr())
			time.Sleep(time.Second) //处理业务1秒
		}(conn)

	}

}

// TCP基本读写操作
func TcpServerRW() {

	// 服务端地址
	// adress := ":8080" //Any IP version
	adress := "127.0.0.1:8080"               //IPv4
	listener, err := net.Listen(tcp, adress) //Listen监听
	if err != nil {
		log.Fatalln(err)
	}
	// 关闭监听
	defer listener.Close()
	log.Println("Server is listening on ", tcp, listener.Addr())

	// 接收请求
	for {
		// 阻塞接受
		conn, err := listener.Accept() //Accept接收
		if err != nil {
			log.Println(err)
		}

		// 处理请求,读写
		go HandleConn(conn)
	}
}

// TCP基本读写操作
func TcpWrite() {

	// 服务端地址
	// adress := ":8080" //Any IP version
	adress := "127.0.0.1:8080"               //IPv4
	listener, err := net.Listen(tcp, adress) //Listen监听
	if err != nil {
		log.Fatalln(err)
	}
	// 关闭监听
	defer listener.Close()
	log.Println("Server is listening on ", tcp, listener.Addr())

	// 接收请求
	for {
		// 阻塞接受
		conn, err := listener.Accept() //Accept接收
		if err != nil {
			log.Println(err)
		}

		// 处理请求,读写
		go HandleConnW(conn)
	}
}

func HandleConn(conn net.Conn) {
	// 日志链接远程地址(client addr)
	log.Printf("accept a new link %s\n", conn.RemoteAddr())
	// 1、保证链接关闭
	defer conn.Close()

	// 2、读写
	wn, err := conn.Write([]byte("send some data from server" + "\n"))
	if err != nil {
		log.Println(err)
	}
	log.Printf("server write len is %d\n", wn)

	// 3、读取客户端数据
	buf := make([]byte, 1024)
	rn, err := conn.Read(buf)
	if err != nil {
		log.Println(err)
		return
	}
	log.Printf("receive data from client,data is %s\n", string(buf[:rn]))
}

func HandleConnW(conn net.Conn) {
	// 日志链接远程地址(client addr)
	log.Printf("accept a new link %s\n", conn.RemoteAddr())
	// 保证链接关闭
	defer conn.Close()

	// 1、严谨判断是否成功
	// data := []byte("send some data from server" + "\n")
	// wn, err := conn.Write(data)
	// if err != nil {
	// 	log.Println(err)
	// }
	// // 严谨判断 没有错误且数据长度不一致，否则写入失败
	// if err == nil && wn != len(data) {
	// 	log.Println("write success,but not all data write to client")
	// }
	// log.Printf("server write len is %d\n", wn)

	// 2、写操作会被阻塞
	// for i := 0; i < 30000; i++ {
	// 	//当无法写入是write会进入阻塞状态 循环30000 实际到16973便阻塞了 根据系统不同数量不同
	// 	data := []byte("send some data from server" + "\n")
	// 	wn, err := conn.Write(data)
	// 	if err != nil {
	// 		log.Println(err)
	// 	}
	// 	log.Printf("%d, server write len is %d\n", i, wn)
	// }

	// 不执行任何操作
	// time.Sleep(10 * time.Second)

	//写入一次
	data := []byte("send some data from servers any thinings" + "\n")
	wn, err := conn.Write(data)
	if err != nil {
		log.Println(err)
	}
	// 严谨判断 没有错误且数据长度不一致，否则写入失败
	if err == nil && wn != len(data) {
		log.Println("write success")
	}
	log.Printf("write success The lenth is %d\n", wn)

	// 3、读取客户端数据
	// buf := make([]byte, 1024)
	// rn, err := conn.Read(buf)
	// if err != nil {
	// 	log.Println(err)
	// 	return
	// }
	// log.Printf("receive data from client,data is %s\n", string(buf[:rn]))
}

// TCP基本读写操作
// 并发的读和写 全双工

func TcpServerRWConcurrency() {
	// 服务端地址
	// adress := ":8080" //Any IP version
	adress := "127.0.0.1:8080"               //IPv4
	listener, err := net.Listen(tcp, adress) //Listen监听
	if err != nil {
		log.Fatalln(err)
	}
	// 关闭监听
	defer listener.Close()
	log.Println("Server is listening on ", tcp, listener.Addr())

	// 接收请求
	for {
		// 阻塞接受
		conn, err := listener.Accept() //Accept接收
		if err != nil {
			log.Println(err)
		}

		// 处理请求,读写
		go HandleConnConcurrency(conn)
	}
}

func HandleConnConcurrency(conn net.Conn) {
	// 日志链接远程地址(client addr)
	log.Printf("accept from #{conn.RemoteAddr()} \n")
	// 1、保证链接关闭
	defer conn.Close()

	// 2、向客户端发送数据 Write 写操作
	wg := sync.WaitGroup{} // 并发计数器
	//并发写 *conn.write通过锁实现的,可保证原子性*
	wg.Add(1)
	go SerWrite(conn, &wg, "0123")
	wg.Add(1)
	go SerWrite(conn, &wg, "abcd")
	wg.Add(1)
	go SerWrite(conn, &wg, "hjkl")

	//并发读
	wg.Add(1)
	go SerRead(conn, &wg)
	wg.Wait() //等待所有并发完成

}

func SerWrite(conn net.Conn, wg *sync.WaitGroup, data string) {
	defer wg.Done() //done 计数器递减
	for {
		// 2、向客户端发送数据 Write 写操作
		wn, err := conn.Write([]byte(data + "\n"))
		if err != nil {
			log.Println(err)
		}
		log.Printf("server write len is %d\n", wn)
		time.Sleep(2 * time.Second)
	}

}

func SerRead(conn net.Conn, wg *sync.WaitGroup) {
	defer wg.Done() //done 计数器递减
	for {
		// 3、读取客户端数据 Read 读操作
		buf := make([]byte, 1024)
		rn, err := conn.Read(buf)
		if err != nil {
			log.Println(err)
			return
		}
		log.Printf("receive data from client,data is %s\n", string(buf[:rn]))
	}

}

// TCP 格式化读写
func TcpServerFormat() {
	// 服务端地址
	adress := "127.0.0.1:8080"               //IPv4
	listener, err := net.Listen(tcp, adress) //Listen监听
	if err != nil {
		log.Fatalln(err)
	}
	// 关闭监听
	defer listener.Close()
	log.Println("Server is listening on ", tcp, listener.Addr())

	// 接收请求
	for {
		// 阻塞接受
		conn, err := listener.Accept() //Accept接收
		if err != nil {
			log.Println(err)
		}
		// 处理请求,读写
		go HandleConnFormat(conn)
	}
}
func HandleConnFormat(conn net.Conn) {
	// 日志链接远程地址(client addr)
	log.Printf("accept from #{conn.RemoteAddr()} \n")
	// 1、保证链接关闭
	defer conn.Close()

	// 2、向客户端发送数据 Write 写操作
	wg := sync.WaitGroup{} // 并发计数器
	//并发写 *conn.write通过锁实现的,可保证原子性*
	wg.Add(1)
	go SerWriteFormat(conn, &wg)
	wg.Wait()
}
func SerWriteFormat(conn net.Conn, wg *sync.WaitGroup) {
	defer wg.Done() //done 计数器递减
	for {
		// 向客户端发送数据
		// 数据编码后发送
		type Message struct {
			ID      uint   `json:"id,omitempty"`
			Code    string `json:"code,omitempty"`
			Content string `json:"content,omitempty"`
		}
		message := Message{
			ID:      uint(rand.Int()),
			Code:    "SERVER-STANDER",
			Content: "This message from server",
		}
		//1、JSON 文本编码
		// 创建编码器
		// encoder := json.NewEncoder(conn)
		// 利用编码器进行编码
		// encode 成功后 会写入conn 已经完成了conn.Write()
		// if err := encoder.Encode(message); err != nil {
		// 	log.Println(err)
		// 	continue
		// }
		// log.Println("message is encoded and sent to client")
		//2、GOB 二进制编码
		encoder := gob.NewEncoder(conn)
		// 利用编码器进行编码
		// encode 成功后 会写入conn 已经完成了conn.Write()
		if err := encoder.Encode(message); err != nil {
			log.Println(err)
			continue
		}
		log.Println("message is encoded and sent to client")
		time.Sleep(1 * time.Second)
	}

}
